package com.whiteape.book.core.manager;

import com.whiteape.book.model.dto.ReplaceRuleBean;
import com.whiteape.book.model.gen.DaoSession;
import com.whiteape.book.model.gen.ReplaceRuleBeanDao;
import com.whiteape.book.net.RetrofitHelper;
import com.whiteape.book.utils.DaoDbHelper;
import com.whiteape.book.utils.FileUtils;
import com.whiteape.book.utils.GsonUtils;
import com.whiteape.book.utils.RxUtils;
import com.whiteape.book.utils.StringUtils;
import com.whiteape.book.utils.URLUtils;

import java.io.File;
import java.util.HashMap;
import java.util.List;

import io.reactivex.Single;

public class ReplaceRuleManager {

    private static volatile ReplaceRuleManager sInstance;
    private ReplaceRuleBeanDao replaceRuleBeanDao;
    private DaoSession daoSession;
    List<ReplaceRuleBean> enabledReplaceRuleBeanList;

    private ReplaceRuleManager() {
        daoSession = DaoDbHelper.getInstance().getSession();
        replaceRuleBeanDao = daoSession.getReplaceRuleBeanDao();
    }

    public static ReplaceRuleManager getInstance() {
        if (sInstance == null) {
            synchronized (ReplaceRuleManager.class) {
                if (sInstance == null) {
                    sInstance = new ReplaceRuleManager();
                }
            }

        }
        return sInstance;
    }

    public void saveReplaceRule(ReplaceRuleBean replaceRuleBean) {
        daoSession.insertOrReplace(replaceRuleBean);
        refreshEnabledReplaceRuleList();
    }


    public void deleteReplaceRule(List<ReplaceRuleBean> replaceRuleBeanList) {
        replaceRuleBeanDao.deleteInTx(replaceRuleBeanList);
        refreshEnabledReplaceRuleList();
    }


    public void deleteReplaceRule(ReplaceRuleBean replaceRuleBean) {
        replaceRuleBeanDao.delete(replaceRuleBean);
        refreshEnabledReplaceRuleList();
    }


    private int importReplaceRuleByJsonLocally(String jsonStr) throws Exception {
        try {

            if (!StringUtils.isJsonFormat(jsonStr)) {
                return -1;
            }
            String str = jsonStr.trim();
            if (StringUtils.isJsonObjFormat(str)) {
                ReplaceRuleBean replaceRuleBean = GsonUtils.string2Obj(str, ReplaceRuleBean.class);
                if (replaceRuleBean.getEnable() == null) {
                    replaceRuleBean.setEnable(true);
                }


                replaceRuleBeanDao.insertOrReplace(replaceRuleBean);
                refreshEnabledReplaceRuleList();
                return 1;
            } else if (StringUtils.isJsonArrFormat(str)) {
                List<ReplaceRuleBean> replaceRuleBeanList = GsonUtils.string2List(str, ReplaceRuleBean.class);
                for (ReplaceRuleBean replaceRuleBean : replaceRuleBeanList) {
                    if (replaceRuleBean.getEnable() == null) {
                        replaceRuleBean.setEnable(true);
                    }
                }
                replaceRuleBeanDao.insertOrReplaceInTx(replaceRuleBeanList);
                refreshEnabledReplaceRuleList();
                return replaceRuleBeanList.size();
            } else {
                return -1;
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }

    }

    public boolean importReplaceRuleByJson(String jsonStr) {
        try {
            int ret = ReplaceRuleManager.getInstance().importReplaceRuleByJsonLocally(jsonStr);
            if (ret == -1) {
                return false;
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public Single<Integer> importReplaceRuleByJsonWithRx(String jsonStr) {

        return Single.create(emitter -> {
            try {
                int ret = importReplaceRuleByJsonLocally(jsonStr);
                if (ret == -1) {
                    emitter.onError(new Throwable("格式不正确"));
                    return;
                }
                emitter.onSuccess(ret);
            } catch (Exception e) {
                e.printStackTrace();
                emitter.onError(e);
            }
        });
    }

    public Single<Integer> importReplaceRuleByUrl(String url) {

        return RetrofitHelper.getInstance()
                .getHttpApiImpl(URLUtils.getBaseUrl(url))
                .get(url.trim(), new HashMap<>())
                .compose(RxUtils::toSimpleSingle)
                .flatMap(stringResponse -> importReplaceRuleByJsonWithRx(stringResponse.body()));
    }

    public Single<Integer> importReplaceRule(String str) {
        if (StringUtils.isEmpty(str)) {
            return Single.create(emitter -> {
                emitter.onError(new Throwable("格式错误"));
            });
        }
        if (StringUtils.isUrlFormat(str)) {
            return importReplaceRuleByUrl(str);
        } else {
            return importReplaceRuleByJsonWithRx(str);
        }

    }

    public Single<Integer> importReplaceRule(File file) {
        String fileContent = FileUtils.getFileContent(file);
        return importReplaceRule(fileContent);
    }

    //TODO 如果导入多个文件，这里我们要求必须是json格式的
    public Single<Integer> importReplaceRule(List<File> fileList) {

        if (fileList != null && fileList.size() == 1) {
            return importReplaceRule(fileList.get(0));
        }

        return Single.create(emitter -> {
            if (fileList == null || fileList.size() == 0) {
                emitter.onError(new Throwable("选择文件错误"));
                return;
            }
            int total = 0;
            for (File file : fileList) {
                String fileContent = FileUtils.getFileContent(file);
                try {
                    int ret = importReplaceRuleByJsonLocally(fileContent);
                    total += ret;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            emitter.onSuccess(total);
        });

    }

    public List<ReplaceRuleBean> getAllEnabledReplaceRules() {
        if (enabledReplaceRuleBeanList == null) {
            refreshEnabledReplaceRuleList();
        }
        return enabledReplaceRuleBeanList;

    }

    public Single<List<ReplaceRuleBean>> getAllReplaceRules() {
        return Single.create(emitter -> {

                emitter.onSuccess(daoSession.getReplaceRuleBeanDao().loadAll());

        });
    }

    private void refreshEnabledReplaceRuleList() {
        enabledReplaceRuleBeanList = daoSession.getReplaceRuleBeanDao().queryBuilder().where(ReplaceRuleBeanDao.Properties.Enable.eq(true))
                .orderDesc(ReplaceRuleBeanDao.Properties.SerialNumber)
                .list();
    }

    public Single<Boolean> insertReplaceRuleByRx(ReplaceRuleBean replaceRuleBean) {
        return Single.create(emitter -> {

            daoSession.startAsyncSession().runInTx(() -> {
                long ret = daoSession.getReplaceRuleBeanDao().insertOrReplace(replaceRuleBean);
                emitter.onSuccess(ret > 0);
                refreshEnabledReplaceRuleList();

            });

        });
    }

    public Boolean insertReplaceRule(ReplaceRuleBean replaceRuleBean) {

        long ret = daoSession.getReplaceRuleBeanDao().insertOrReplace(replaceRuleBean);
        refreshEnabledReplaceRuleList();
        return ret > 0;


    }

    public void insertReplaceRuleList(List<ReplaceRuleBean> replaceRuleBeanList) {
        if (replaceRuleBeanList == null || replaceRuleBeanList.size() <= 0) {
            return;
        }

        daoSession.getReplaceRuleBeanDao().insertOrReplaceInTx(replaceRuleBeanList);
        refreshEnabledReplaceRuleList();

    }
}
